#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>

#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_i2c.h"
#include "iot_gpio.h"
#include "iot_pwm.h"
#include "iot_errno.h"
#include "hi_io.h"
#include "hi_adc.h"
#include "aht20.h"
#include "oled_ssd1306.h"
#include "config_params.h"

#include "assistant.h"
#include "cc2530.h"
#include "hi_gpio.h"
#include "hi_pwm.h"
//蜂鸣器GPIO
#define BEEP_PIN_NAME HI_IO_NAME_GPIO_9
#define BEEP_PIN_FUNCTION 5
#define BEEP_PWM_PORT_PWM0 0
// end 蜂鸣器

#define GAS_SENSOR_CHAN_NAME HI_ADC_CHANNEL_5

//甲烷引脚
#define METHANE_SENSOR_CHAN_NAME 5
//加湿器
#define Humidifier_PIN_NAME 10
#define Humidifier_IO_FUNC_GPIO HI_IO_FUNC_GPIO_10_GPIO
//空气净化器
#define AIRCLEANER_PIN_NAME HI_IO_NAME_GPIO_11
#define AIRCLEANER_IO_FUNC_GPIO HI_IO_FUNC_GPIO_11_GPIO
//红外
#define INFRARED_GPIO_PIN HI_IO_NAME_GPIO_8
#define INFRARED_IO_FUNC_PIN HI_IO_FUNC_GPIO_8_GPIO

#define AHT20_BAUDRATE 400 * 1000
#define AHT20_I2C_IDX 0

#define ADC_RESOLUTION 2048
#define IOT_GPIO_KEY 5

#define MQ135_GPIO_PIN HI_ADC_CHANNEL_7

#define CAL_PPM 20  //校准环境中PPM值
#define RL 1        //RL阻值
static float R0;    //元件在洁净空气中的阻值

float g_humidity = 0.0f;
float g_temperature = 0.0f;
float g_gasValue = 0.0f;
int g_infra = 0;
float g_mq2Value = 0;
int g_alarm = 0;

float ConvertToVoltage(unsigned short data)
{
    return (float)data * 1.8 * 4 / 4096;
}

static void infra_alarm(char *arg)
{
    g_infra = 1;
    g_alarm = 1;
    // IoTPwmStart(HI_PWM_PORT_PWM0, 50, 4000);
    // hi_gpio_set_ouput_val(HI_IO_NAME_GPIO_9, !g_infra);
    printf("infra_red=%d\n", g_infra);

    
}
static void infra_clear_alarm(char *arg)
{
    g_infra = !g_infra;

    printf("infra_red=%d\n", g_infra);

    // if (g_infra == 0)
    //     IoTPwmStop(HI_PWM_PORT_PWM0);
    // else
    //     IoTPwmStart(HI_PWM_PORT_PWM0, 50, 4000);
}

static float GetM135Value()
{
    unsigned int ret;
    unsigned short data;
    ret = hi_adc_read(HI_ADC_CHANNEL_7, &data, HI_ADC_EQU_MODEL_8, HI_ADC_CUR_BAIS_DEFAULT, 0xff);
    if (ret != IOT_SUCCESS)
    {
        printf("HI_ADC_CHANNEL_7 ADC Read Fail\n");
    }
    return (float)data/4095*3300/1000;
}
/**
 * @brief 获取电压值函数
 * 
 */
static float GetMQ2Voltage(void)
{
    unsigned int ret;
    unsigned short data;

    ret = hi_adc_read(HI_ADC_CHANNEL_7, &data, HI_ADC_EQU_MODEL_8, HI_ADC_CUR_BAIS_DEFAULT, 0xff);
    if (ret != IOT_SUCCESS)
    {
        printf("HI_ADC_CHANNEL_7 ADC Read Fail\n");
    }
    return (float)data * 1.8 * 4 / 4096.0;
}
/**
 * @brief 获取PPM函数
 * 
 */
float Get_MQ2_PPM(void)
{
    float voltage, RS, ppm;

    voltage = GetMQ2Voltage();
    RS = (5 - voltage) / voltage * RL;    //计算RS
    ppm = 613.9f * pow(RS / R0, -2.074f); //计算ppm

    printf("M135: Voltage=%.2f,RS=%.2f,R0=%.2f,PPM=%.2f\n", voltage, RS, R0, ppm);
    return ppm;
}
/**
 * @brief 传感器校准函数
 * 
 */
void MQ2_PPM_Calibration(void)
{
    float voltage = GetMQ2Voltage();
    float RS = (5 - voltage) / voltage * RL;
    R0 = RS / pow(CAL_PPM / 613.9f, 1 / -2.074f);
}
/**
 * @brief 初始化
 *
 */
int Assistant_Init(void)
{
    // cc2530_uart_init();
    // // LED1
    // hi_io_set_func(HI_IO_NAME_GPIO_9, HI_IO_FUNC_GPIO_9_GPIO);
    // hi_gpio_set_dir(HI_GPIO_IDX_9, HI_GPIO_DIR_OUT);
    // hi_gpio_set_ouput_val(HI_GPIO_IDX_9, 1);
    //加湿器
    hi_io_set_func(Humidifier_PIN_NAME, Humidifier_IO_FUNC_GPIO);
    hi_gpio_set_dir(Humidifier_PIN_NAME, HI_GPIO_DIR_OUT);
    hi_gpio_set_ouput_val(Humidifier_PIN_NAME, HI_GPIO_VALUE0);

    //蜂鸣器
    hi_io_set_func(BEEP_PIN_NAME, BEEP_PIN_FUNCTION);
    hi_gpio_set_dir(BEEP_PIN_NAME, HI_GPIO_DIR_OUT);
    hi_pwm_init(HI_PWM_PORT_PWM0);
    hi_pwm_set_clock(PWM_CLK_160M);

    //空气净化器
    hi_io_set_func(AIRCLEANER_PIN_NAME, AIRCLEANER_IO_FUNC_GPIO);
    hi_gpio_set_dir(AIRCLEANER_PIN_NAME, HI_GPIO_DIR_OUT);
    hi_gpio_set_ouput_val(AIRCLEANER_PIN_NAME, HI_GPIO_VALUE0);    


    //红外
    hi_io_set_func(INFRARED_GPIO_PIN, INFRARED_IO_FUNC_PIN);
    hi_gpio_set_dir(INFRARED_GPIO_PIN, HI_GPIO_DIR_IN);
    hi_io_set_pull(INFRARED_GPIO_PIN, HI_IO_PULL_UP);
    hi_gpio_register_isr_function(INFRARED_GPIO_PIN, HI_INT_TYPE_EDGE, HI_GPIO_EDGE_RISE_LEVEL_HIGH, infra_alarm, NULL);
    
    usleep(1000000);        // 开机1s后进行校准
    MQ2_PPM_Calibration();
}

/**
 * @brief 读取传感器信息
 *
 */
int Assistant_Read_Data(Assistant_Data_TypeDef *data)
{
    uint32_t retval = 0;
    retval = AHT20_StartMeasure();

    if (retval != IOT_SUCCESS)
    {
        printf("trigger measure failed!\r\n");
    }

    retval = AHT20_GetMeasureResult(&g_temperature, &g_humidity);
    if (retval != IOT_SUCCESS)
    {
        printf("get humidity data failed!\r\n");
    }

    unsigned short adcdata = 0;
    if (hi_adc_read(GAS_SENSOR_CHAN_NAME, &adcdata, HI_ADC_EQU_MODEL_4, HI_ADC_CUR_BAIS_DEFAULT, 0) == IOT_SUCCESS)
    {
        float Vx = ConvertToVoltage(adcdata);
        float gasSensorResistance = 0.0f;
        // Vcc            ADC            GND
        //  |    ______   |     ______   |
        //  +---| MG-2 |---+---| 1kom |---+
        //       ------         ------
        // 查阅原理图，ADC 引脚位于 1K 电阻和燃气传感器之间，燃气传感器另一端接在 5V 电源正极上
        // 串联电路电压和阻止成正比：
        // Vx / 5 == 1kom / (1kom + Rx)
        //   => Rx + 1 == 5/Vx
        //   =>  Rx = 5/Vx - 1
        gasSensorResistance = 5 / Vx - 1;
        // printf("gasSensorResistance is %f\r\n", gasSensorResistance);
        //甲烷浓度计算
        g_gasValue = 1 / (1 + gasSensorResistance) * (-2593) + 78;

        if (g_gasValue < 0)
        {
            g_gasValue = 0;
        }
    }


    // g_mq2Value = Get_MQ2_PPM();
    // printf("ppm:%.3f \n", g_mq2Value);
    
    // zigbee串口读取
    //  uint8_t uart_buff_ptr = 0;
    //  if (cc2530_uart_read(&uart_buff_ptr))
    //  {
    //      g_infra = uart_buff_ptr;
    //      printf("AS312 Value = %d\r\n", uart_buff_ptr);
    //  }
    // IO直接读取
    // g_infra = HI_GPIO_VALUE0;
    // hi_gpio_get_input_val(INFRARED_GPIO_PIN, &g_infra);

    data->Humidity = g_humidity;
    data->Infra = g_infra;
    data->Methane = g_gasValue;
    data->Temperature = g_temperature;
    data->Smoke = 0;
    data->AirQuality = GetM135Value();

    return IOT_SUCCESS;
}
/**
 * @brief 加湿器开关
 *
 */
int Assistant_Humidifier_Status(Status_ENUM status)
{
    if (status == ON)
        hi_gpio_set_ouput_val(Humidifier_PIN_NAME, HI_GPIO_VALUE1);
    else
        hi_gpio_set_ouput_val(Humidifier_PIN_NAME, HI_GPIO_VALUE0);
    return 0;
}
/**
 * @brief 空气净化器开关
 *
 */
int Assistant_AirCtl_Status(Status_ENUM status)
{
    if (status == ON)
        hi_gpio_set_ouput_val(AIRCLEANER_PIN_NAME, HI_GPIO_VALUE1);
    else
        hi_gpio_set_ouput_val(AIRCLEANER_PIN_NAME, HI_GPIO_VALUE0);
    return 0;
}
/**
 * @brief 
 * 
 */
int Assistant_Alarm_Control(Status_ENUM status)
{
    if(status == OFF)
        hi_pwm_stop(HI_PWM_PORT_PWM0);
    else
        hi_pwm_start(HI_PWM_PORT_PWM0, 50, 4000);
}
/**
 * @brief 给Zigbee发送消息
 *
 */
int Assistant_CC2530_Write(void)
{

    return 0;
}